package com.movie.filter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.movie.entity.User;
import com.movie.vo.Result;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import utils.JsonUtils;
import utils.JwtUtils;
import utils.RsaUtils;

import java.net.URI;
import java.security.PublicKey;

@Component
public class GlobalAuthFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        URI uri = request.getURI();
        String[] white={"movie","user","index","keyword","films","star","cinema"};
        for (String s : white) {
            if (uri.getPath().contains(s)){
                return chain.filter(exchange);//放行
            }
        }

        //判断请求头是否有token
        String token = request.getHeaders().getFirst("token");
        if (token==null){

            return response(response,new Result(false,"请登录"));
        }



        PublicKey publicKey = null;
        //加载公钥
        try {
            publicKey = RsaUtils.getPublicKey(  ResourceUtils.getFile("classpath:ras.pub").getPath());

        } catch (Exception e) {
            e.printStackTrace();

        }

//        校验令牌
        try {
            User infoFromToken = (User) JwtUtils.getInfoFromToken(token, publicKey, User.class);
            ServerHttpRequest newRequest = request.mutate().header("token", JsonUtils.toString(infoFromToken)).build();
            ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();
           return chain.filter(newExchange);
        } catch (MalformedJwtException e){//jwt解析异常

            return response(response, new Result(false,"解析异常") );

        }catch (ExpiredJwtException e){
            return response(response, new Result(false,"令牌过期"));
        }catch (Exception e){
            return response(response, new Result(false,"其他异常"));
        }
    }

//数字越小越先执行
    @Override
    public int getOrder() {
        return 0;
    }

    private Mono<Void> response(ServerHttpResponse response, Result res){
        //不能放行，直接返回，返回json信息
        response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");



        ObjectMapper objectMapper = new ObjectMapper();
        String jsonStr = null;
        try {
            jsonStr = objectMapper.writeValueAsString(res);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }


        DataBuffer dataBuffer = response.bufferFactory().wrap(jsonStr.getBytes());

        return response.writeWith(Flux.just(dataBuffer));//响应json数据
    }
}
